module themexec.define;

//. the main app needs these.
public import std.stdio;
public import std.string;
public import std.conv;
public import std.file;
public import std.path;

//. only the class needs these.
private import std.stream;
private import std.regexp;
private import std.process;
private import std.c.time;

//. the structure to hold the commands from the text file.
struct cmd_s {
	char[] title;
	char[] str;
};

//. the main class for theme execution.
class themeInfo {

	private char[] name;
	private char[] filename;
	private int cmd_count;
	private cmd_s[] cmd;
	
	private File f;
	
	//. set the theme.
	public void set(char[] str) {
	
		//. test input.
		if(str.length > 0) { this.name = str; }
		else { throw new Error("must specify a theme."); }

		//. test theme file.
		this.filename = expandTilde("~/.themexec/" ~ str ~ ".theme");
		if(!exists(this.filename)) { throw new Error("unable to open theme: " ~ this.filename); }
		
		//. open and parse.
		f = new File(this.filename,FileMode.In);
		while(!f.eof()) {
			if(auto m = std.regexp.search(f.readLine()," \\$ ")) {
				
				this.cmd.length = this.cmd_count + 1;
				
				this.cmd[cmd_count].title = m.pre;
				this.cmd[cmd_count].str = m.post;
				
				this.cmd_count++; m = null;
			}
		} f.close();
	}
	
	//. print the commands to console.
	public void write_cmds() {
		foreach(int a, cmd_s c; this.cmd) {
			writefln("[%s]$ %s",c.title,c.str);
		}
	}
	
	//. themexec the loaded them.
	public void execute(bool verbose,  bool pseudorun, bool nowaitret, int wait) {
	
		int sysreturn;	
	
		if(this.name.length == 0) {
			throw new Error("no themexec to apply.");
		}	
	
		foreach(int a, cmd_s c; this.cmd) {
		
			if(verbose) {
				writefln("[themexec:%s]$ %s",c.title,c.str);
			}
			
			if(!pseudorun) {
			
				if(nowaitret) { sysreturn = system(c.str ~ " &> /dev/null &"); }
				else { sysreturn = system(c.str); }
				
				switch(sysreturn) {
					case(-1): {
						writefln("[themexec:%s] system exec failed",c.str);
						sysreturn = 0;
						break;					
					}
					case(0): {
						//. application reports clean exec.
						break;
					}
					default: {
						writefln("[themexec:%s] application reports error",c.str);
						sysreturn = 0;	
						break;					
					}
				}				

			}
			
			if(wait) { usleep(wait * 1000); }
			
		}	
	}
	
};